# -*- coding: UTF-8 -*-
import random, hashlib
import requests, hmac, time, base64, urllib.parse
from itsecure.config import Secret,Config

secret = Secret()
config = Config()
my_AC_secret = secret.get_acSecret()
base_url="http://192.168.100.100:9999"
dingding_base_url="https://oapi.dingtalk.com/robot/send"
access_token= secret.get_acAccessToken()
headers={"Content-Type": "application/json;charset=utf-8"}

location={
    "all_policy": "/v1/policy/netpolicy",
    "user_policy": "/v1/user/netpolicy"
}


def dingding_notify(title, content, msg_type="markdown", btn_list='', if_notice=True):
    if if_notice:
        timestamp = str(
            round(time.time() * 1000))  # 注意签名有过期时间，超过时间则无效，所以每次请求都生成一个新的timestamp，签名生成时间和发送时间请保持在timestampms以内
        ddsecret = secret.get_AC_dingdingSecret()
        # ddsecret = 'SEC91f1b99e35fb2894f4f23bb80dd1c3a7f9dc4205c3a4c104d3fe903f3270eefa'
        secret_enc = ddsecret.encode('utf-8')
        string_to_sign = '{}\n{}'.format(timestamp, ddsecret)
        string_to_sign_enc = string_to_sign.encode('utf-8')
        hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
        sign = urllib.parse.quote_plus(base64.b64encode(hmac_code))
        dingding_url = dingding_base_url + '?access_token=' + access_token + '&timestamp=' + timestamp + '&sign=' + sign
        print(content)
        content = '<font color="#264D9E">---AC服务器通知---</font>\n\n' + content
        msg = {"msgtype": msg_type,
               "text": {"content": content},
               "markdown": {
                   "title": title,
                   "text": content,
               },
               "actionCard": {
                   "title": title,
                   "text": content,
                   "hideAvatar": "0",
                   "btnOrientation": "1",
                   "btns": btn_list
               }
               }
        result = requests.post(dingding_url, headers=headers, json=msg)
        print('发送钉钉结果：', result)


def try_except(func):
    def wrap(*args, **kwargs):
        try:
            print('@try_except@')
            r = func(*args, **kwargs)
        except Exception as e:
            r = '程序错误！' + str(e)
            print({'error': e})
            dingding_notify('错误', r)
        finally:
            return r

    return wrap


class ACapi:
    def __init__(self, request_data):
        self.request_data = request_data

    #生成随机字符串(纯数字)
    def generate_random_string(self, length):
        random_string = ''.join(str(random.randint(0, 9)) for _ in range(length))
        return random_string

    #将密钥和随机字符串拼接并生成md5值
    def generate_md5(self, message):
        md5 = hashlib.md5()  # 创建一个md5对象
        md5.update(message.encode('utf-8'))  # 使用utf-8编码消息
        return md5.hexdigest()  # 返回十六进制的哈希值

    def get_params(self, param,user='user'):
        random_str=self.generate_random_string(16)
        print('random:\t',random_str)
        message = my_AC_secret+random_str
        md5_value = self.generate_md5(message)
        print('md5:\t',md5_value)
        params = {
            'all_policy': {
                "random": random_str,
                "md5": md5_value
            },
            'user_policy': {
                "user": user,
                "random": random_str,
                "md5": md5_value
            }
        }
        return params[param]

    def get_api_return(self, param,user='user'):
        try:
            response=requests.get(base_url+location[param], params=get_params(param,user))
            json_get=response.json()
            r=json_get
        except Exception as e:
            print('error:出问题了！')
            r='error'+str(e)
        finally:
            return r

    #获取所有策略
    @try_except
    def get_all_policy(self):
        response=self.get_api_return('all_policy')
        print('response',response)
        if response['message'] != 'Successfully':
            print('get_allpol_err',response)
            content=str(response)
        else:
            content="**所有上网策略：**\n"
            print(content)
            for i in range(len(response['data'])):
                print(i+1,'-',response['data'][i]["policy_info"]["name"],',status=',response['data'][i]["policy_info"]["status"])
                color="#C40000"
                if response['data'][i]["policy_info"]["status"]:
                    color="#34AB19"
                content='{}1. <font color={}>{}</font>\n\n'.format(content,color,response['data'][i]["policy_info"]["name"])
        dingding_notify('获取所有上网策略',content)

    #获取用户的所有策略
    @try_except
    def get_user_policy(self, user):
        response=self.get_api_return('user_policy',user)
        print('get_user-response',response)
        if response['message'] != 'Successfully':
            print('get_user_err',response)
            content=str(response)
        else:
            content='**<font color="#ff0000">{}</font>用户所属所有策略：**\n'.format(user)
            print(content)
            for i in range(len(response['data'])):
                print(i+1,'-',response['data'][i])
                content='{}1. {}\n\n'.format(content,response['data'][i])
        btn_list=[
            {
                "title": "todesk-ON",
                "actionURL": "https://frp-dtrobot.gyenno.com/api/acbtnclick?name="+user+"&opr=todesk-add"
            },
            {
                "title": "todesk-OFF",
                "actionURL": "https://frp-dtrobot.gyenno.com/api/acbtnclick?name="+user+"&opr=todesk-del"
            },
            {
                "title": "wps-ON",
                "actionURL": "https://frp-dtrobot.gyenno.com/api/acbtnclick?name="+user+"&opr=wps-add"
            },
            {
                "title": "wps-OFF",
                "actionURL": "https://frp-dtrobot.gyenno.com/api/acbtnclick?name="+user+"&opr=wps-del"
            },
            {
                "title": "netdisk-ON",
                "actionURL": "https://frp-dtrobot.gyenno.com/api/acbtnclick?name="+user+"&opr=netdisk-add"
            },
            {
                "title": "netdisk-OFF",
                "actionURL": "https://frp-dtrobot.gyenno.com/api/acbtnclick?name="+user+"&opr=netdisk-del"
            }
        ]
        dingding_notify('获取用户策略', content, 'actionCard', btn_list=btn_list)

    #用户添加及删除策略
    @try_except
    def modify_user_policy(self, user,opr,policy):
        opr_arr={'add': '添加', 'del': '删除'}
        random_str= self.generate_random_string(16)
        message = my_AC_secret+random_str
        md5_value = self.generate_md5(message)
        json_data = {
            "random": random_str,
            "md5": md5_value,
            "opr": opr,
            "user": user,
            "policy": [
                policy
            ]
        }
        params=self.get_params('user_policy',user)
        print('---usermodify---\n',params)
        print('---usermodify---\n',json_data)
        r=requests.post(base_url+location['user_policy'], params=params, headers=headers, json=json_data)
        response=r.json()
        print(opr_arr[opr],'用户策略：', response['message'])
        if response['message'] != 'Successfully':
            print('-usermodify-not successes!!!')
            content=r.text
        else:
            content='<font color="#ff0000">{}</font>用户{}策略<font color="#ff0000">{}</font>成功！'.format(user,opr_arr[opr],policy)
        dingding_notify(f'{opr_arr[opr]}策略',content)

    def process_apply(self, msgBody):
        print('这是ac的处理程序！！！')
        switch={'apply': 'add', 'revoke': 'del'}
        user_list=msgBody['apply_user']
        # opr_dict={'todesk': 'todesk控制', 'wps': 'wps云同步(仅下载)', 'netdisk': '开放网盘（仅下载）'}
        if msgBody['apply_type'] == '远程办公':
            for i in user_list:
                self.modify_user_policy(i['name'], switch[msgBody['action_type']], 'todesk控制')
        if msgBody['apply_type'] == '网盘':
            for i in user_list:
                self.modify_user_policy(i['name'], switch[msgBody['action_type']], '开放网盘（仅下载）')
        if msgBody['apply_type'] == 'WPS':
            for i in user_list:
                self.modify_user_policy(i['name'], switch[msgBody['action_type']], 'wps云同步(仅下载)')



    def help_info(self,):
        content='**使用帮助：**\n\n* 显示此帮助<font color="#ff0000">（h）</font>\n\n* 列出所有策略<font color="#ff0000">（l）</font>\n\n* 列出某用户所关联的策略<font color="#ff0000">（u 用户名）</font>\n\n* 给某用户增加关联一个策略<font color="#ff0000">（m 用户名 add 策略名）</font>\n\n* 给某用户取消关联一个策略<font color="#ff0000">（m 用户名 del 策略名）</font>'
        dingding_notify('帮助',content)

    def err_info(self, type):
        if type=='noTypeErr':
            dingding_notify('错误','发生错误：没有所要求的操作！')
        else:
            dingding_notify('错误','发生不明错误')

    def process_request(self):
        if self.request_data['message'] == 'h':
            self.help_info()
    '''
    #生成随机字符串(字母)
    # def generate_random_string(length):
    #     letters = string.ascii_letters  # 包含所有字母的字符串
    #     random_string = ''.join(random.choice(letters) for _ in range(length))
    #     return random_string
    '''

if __name__ == '__main__':
    print('only for module')
    # get_all_policy()
    # dingding_notify({"msgtype": "text","text": {"content": "AC服务器"}})


